package it.graph;

import java.awt.EventQueue;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.GridBagLayout;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.Insets;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.swing.border.BevelBorder;
import java.awt.Component;
import javax.swing.Box;
import javax.swing.SwingConstants;

import org.jgraph.JGraph;
import org.jgraph.graph.DefaultGraphModel;
import org.jgrapht.alg.DijkstraShortestPath;
import org.jgrapht.alg.KruskalMinimumSpanningTree;
import org.jgrapht.graph.DefaultWeightedEdge;

import java.awt.Color;

public class GUI {

	private JFrame frmGraphtheory;
	private JTextField localitaTextField;
	private JTabbedPane algTabbedPane;
	private JPanel Mappa;
	private JLabel lblTestoRicerca;
	private JLabel lblLatitudine;
	private JTextField latitudineText;
	private JLabel lblLongitudine;
	private JTextField longitudineText;
	private JLabel lblScala;
	private JSpinner scalaSpinner;
	private JLabel label;
	private JSpinner zoomSpinner;
	private JLabel lblFormato;
	private JComboBox formatoComboBox;
	private JLabel lblMappa;
	private JComboBox mappaComboBox;
	private JButton btnDownload;
	private JLabel lblDimensione;
	private JComboBox dimensioneComboBox;	
	private BufferedImage map;
	private JPanel Cammino;
	private JPanel Albero;
	private JButton btnGrafo;
	private JLabel lblPercorsi;
	private JSpinner percorsiSpinner;
	private JLabel lblNodo1;
	private JLabel lblNodo2;
	private JComboBox nodo1ComboBox;
	private JComboBox nodo2ComboBox;
	private JButton btnDijkstra;
	private JLabel lblKruskal;
	private JButton btnKruskal;
	private JLabel lblDijkstra;
	private GridBagLayout gbl_mappaPanel;
	
	private static final String staticMapsURL = "http://maps.googleapis.com/maps/api/staticmap?";
//	private static final String jsonGeocodingURL = "http://maps.googleapis.com/maps/api/geocode/json?";
	
	//Parametri per StaticMaps
	private static final String c = "center=";
	private static final String z = "zoom=";
	private static final String sc = "scale=";
	private static final String si = "size=";
	private static final String f = "format=";
	private static final String t = "maptype=";
	
	/*
	 *  Utilizzare Geocoding??
	 * 	//Parametri per Geocoding
	 * 	private static final String add = "address=";
	 *  private static final String ll = "latlng=";
	 */
	
	private static final String sensor = "sensor=false";
	private static final String and = "&";
	
	static int deltaX = 0;
	static int deltaY = 0;
	static int scala;
	static int zoom;
	
	static Double lat;
	static Double lng;
	
	static Double confineN;
	static Double confineS;
	static Double confineW;
	static Double confineE;
	
	private ArrayList<String> modelNodo = new ArrayList<String>();	//Nodi del grafo
	
	protected ConvPoint clickedPoint;
	private Component sinistra;
	private Component destra;
	private Component basso;
	private Component alto;
	private MapMouseActionListener mapMouse;
	
	private JPanel mappaPanel;
	private JLabel mappaLabel;
	private JScrollPane mappaScrollPane;
	private JGraph jg;
	
	public static Grafo grafo = null;
	public static JButton btnFine;

	private JTextField textCurrent;
	private JTextField costoTextField;
	private JLabel lblCosto;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GUI window = new GUI();
					window.frmGraphtheory.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public GUI() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmGraphtheory = new JFrame();
		frmGraphtheory.setTitle("graphTheory");

		//Frame iniziale fullsrceen
		frmGraphtheory.setSize(new Dimension(1024,640));
		frmGraphtheory.setExtendedState(JFrame.MAXIMIZED_BOTH);
		frmGraphtheory.setUndecorated(false);
		
		frmGraphtheory.getContentPane().setLayout(new BoxLayout(frmGraphtheory.getContentPane(), BoxLayout.X_AXIS));
		
		mappaPanel = new JPanel();
		frmGraphtheory.getContentPane().add(mappaPanel);
		gbl_mappaPanel = new GridBagLayout();
		gbl_mappaPanel.columnWidths = new int[] {0, 0, 0};
		gbl_mappaPanel.rowHeights = new int[] {0, 0, 0};
		gbl_mappaPanel.columnWeights = new double[]{0.0, 0.0, 0.0};
		gbl_mappaPanel.rowWeights = new double[]{0.0, 0.0};
		mappaPanel.setLayout(gbl_mappaPanel);
		
		sinistra = Box.createHorizontalStrut(20);
		GridBagConstraints gbc_sinistra = new GridBagConstraints();
		gbc_sinistra.insets = new Insets(0, 0, 5, 5);
		gbc_sinistra.gridx = 0;
		gbc_sinistra.gridy = 1;
		mappaPanel.add(sinistra, gbc_sinistra);
		
		mappaScrollPane = new JScrollPane();
		mappaScrollPane.setViewportBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
		GridBagConstraints gbc_mappaScrollPane = new GridBagConstraints();
		gbc_mappaScrollPane.fill = GridBagConstraints.BOTH;
		gbc_mappaScrollPane.insets = new Insets(0, 0, 5, 5);
		gbc_mappaScrollPane.gridx = 1;
		gbc_mappaScrollPane.gridy = 1;
		mappaPanel.add(mappaScrollPane, gbc_mappaScrollPane);
		
		destra = Box.createHorizontalStrut(20);
		GridBagConstraints gbc_destra = new GridBagConstraints();
		gbc_destra.insets = new Insets(0, 0, 5, 0);
		gbc_destra.gridx = 2;
		gbc_destra.gridy = 1;
		mappaPanel.add(destra, gbc_destra);
		
		alto = Box.createVerticalStrut(20);
		GridBagConstraints gbc_alto = new GridBagConstraints();
		gbc_alto.insets = new Insets(0, 0, 5, 5);
		gbc_alto.gridx = 1;
		gbc_alto.gridy = 0;
		mappaPanel.add(alto, gbc_alto);
		
		basso = Box.createVerticalStrut(20);
		GridBagConstraints gbc_basso = new GridBagConstraints();
		gbc_basso.insets = new Insets(0, 0, 0, 5);
		gbc_basso.gridx = 1;
		gbc_basso.gridy = 2;
		mappaPanel.add(basso, gbc_basso);
		
		algTabbedPane = new JTabbedPane(JTabbedPane.TOP);
		algTabbedPane.setPreferredSize(new Dimension(320, 0));
		algTabbedPane.setMaximumSize(new Dimension(400, 32767));
		algTabbedPane.setMinimumSize(new Dimension(400, 0));
		frmGraphtheory.getContentPane().add(algTabbedPane);
		
		Mappa = new JPanel();
		algTabbedPane.addTab("Mappa", null, Mappa, null);
		GridBagLayout gbl_Mappa = new GridBagLayout();
		gbl_Mappa.columnWidths = new int[]{65, 106, 32, 106, 0};
		gbl_Mappa.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_Mappa.columnWeights = new double[]{0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		gbl_Mappa.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		Mappa.setLayout(gbl_Mappa);
		
		lblTestoRicerca = new JLabel("Località");
		lblTestoRicerca.setVisible(false);
		lblTestoRicerca.setEnabled(false);
		GridBagConstraints gbc_lblTestoRicerca = new GridBagConstraints();
		gbc_lblTestoRicerca.insets = new Insets(0, 0, 5, 5);
		gbc_lblTestoRicerca.gridx = 0;
		gbc_lblTestoRicerca.gridy = 0;
		Mappa.add(lblTestoRicerca, gbc_lblTestoRicerca);
		
		localitaTextField = new JTextField();
		localitaTextField.setVisible(false);
		localitaTextField.setEnabled(false);
		GridBagConstraints gbc_localitaTextField = new GridBagConstraints();
		gbc_localitaTextField.gridwidth = 3;
		gbc_localitaTextField.insets = new Insets(0, 0, 5, 0);
		gbc_localitaTextField.fill = GridBagConstraints.BOTH;
		gbc_localitaTextField.gridx = 1;
		gbc_localitaTextField.gridy = 0;
		Mappa.add(localitaTextField, gbc_localitaTextField);
		localitaTextField.setColumns(10);
		
		lblLatitudine = new JLabel("Lat");
		GridBagConstraints gbc_lblLatitudine = new GridBagConstraints();
		gbc_lblLatitudine.insets = new Insets(0, 0, 5, 5);
		gbc_lblLatitudine.gridx = 0;
		gbc_lblLatitudine.gridy = 1;
		Mappa.add(lblLatitudine, gbc_lblLatitudine);
		
		latitudineText = new JTextField();
		GridBagConstraints gbc_latitudineText = new GridBagConstraints();
		gbc_latitudineText.fill = GridBagConstraints.BOTH;
		gbc_latitudineText.insets = new Insets(0, 0, 5, 5);
		gbc_latitudineText.gridx = 1;
		gbc_latitudineText.gridy = 1;
		Mappa.add(latitudineText, gbc_latitudineText);
		//Inizializzati con la Puglia
		latitudineText.setText(Double.toString(41.008099));
		
		lblLongitudine = new JLabel("Long");
		GridBagConstraints gbc_lblLongitudine = new GridBagConstraints();
		gbc_lblLongitudine.insets = new Insets(0, 0, 5, 5);
		gbc_lblLongitudine.gridx = 0;
		gbc_lblLongitudine.gridy = 2;
		Mappa.add(lblLongitudine, gbc_lblLongitudine);
		
		longitudineText = new JTextField();
		GridBagConstraints gbc_longitudineText = new GridBagConstraints();
		gbc_longitudineText.fill = GridBagConstraints.BOTH;
		gbc_longitudineText.insets = new Insets(0, 0, 5, 5);
		gbc_longitudineText.gridx = 1;
		gbc_longitudineText.gridy = 2;
		Mappa.add(longitudineText, gbc_longitudineText);
		//Inizializzati con la Puglia
		longitudineText.setText(Double.toString(16.727239));
		
		lblScala = new JLabel("Scala");
		GridBagConstraints gbc_lblScala = new GridBagConstraints();
		gbc_lblScala.insets = new Insets(0, 0, 5, 5);
		gbc_lblScala.gridx = 0;
		gbc_lblScala.gridy = 3;
		Mappa.add(lblScala, gbc_lblScala);
		
		scalaSpinner = new JSpinner();
		scalaSpinner.setModel(new SpinnerNumberModel(1, 1, 2, 1));
		GridBagConstraints gbc_scalaSpinner = new GridBagConstraints();
		gbc_scalaSpinner.insets = new Insets(0, 0, 5, 5);
		gbc_scalaSpinner.gridx = 1;
		gbc_scalaSpinner.gridy = 3;
		Mappa.add(scalaSpinner, gbc_scalaSpinner);
		
		label = new JLabel("Zoom");
		GridBagConstraints gbc_label = new GridBagConstraints();
		gbc_label.insets = new Insets(0, 0, 5, 5);
		gbc_label.gridx = 2;
		gbc_label.gridy = 3;
		Mappa.add(label, gbc_label);
		
		zoomSpinner = new JSpinner();
		zoomSpinner.setModel(new SpinnerNumberModel(10, 1, 21, 1));
		GridBagConstraints gbc_zoomSpinner = new GridBagConstraints();
		gbc_zoomSpinner.insets = new Insets(0, 0, 5, 0);
		gbc_zoomSpinner.gridx = 3;
		gbc_zoomSpinner.gridy = 3;
		Mappa.add(zoomSpinner, gbc_zoomSpinner);
		
		lblFormato = new JLabel("Formato");
		GridBagConstraints gbc_lblFormato = new GridBagConstraints();
		gbc_lblFormato.insets = new Insets(0, 0, 5, 5);
		gbc_lblFormato.gridx = 0;
		gbc_lblFormato.gridy = 4;
		Mappa.add(lblFormato, gbc_lblFormato);
		
		formatoComboBox = new JComboBox();
		formatoComboBox.setModel(new DefaultComboBoxModel(new String[] {"png32", "gif", "jpeg", "jpeg-baseline"}));
		GridBagConstraints gbc_formatoComboBox = new GridBagConstraints();
		gbc_formatoComboBox.insets = new Insets(0, 0, 5, 5);
		gbc_formatoComboBox.fill = GridBagConstraints.VERTICAL;
		gbc_formatoComboBox.gridx = 1;
		gbc_formatoComboBox.gridy = 4;
		Mappa.add(formatoComboBox, gbc_formatoComboBox);
		
		lblMappa = new JLabel("Mappa");
		GridBagConstraints gbc_lblMappa = new GridBagConstraints();
		gbc_lblMappa.anchor = GridBagConstraints.EAST;
		gbc_lblMappa.insets = new Insets(0, 0, 5, 5);
		gbc_lblMappa.gridx = 0;
		gbc_lblMappa.gridy = 5;
		Mappa.add(lblMappa, gbc_lblMappa);
		
		mappaComboBox = new JComboBox();
		mappaComboBox.setModel(new DefaultComboBoxModel(new String[] {"roadmap", "satellite", "terrain", "hybrid"}));
		GridBagConstraints gbc_mappaComboBox = new GridBagConstraints();
		gbc_mappaComboBox.insets = new Insets(0, 0, 5, 5);
		gbc_mappaComboBox.fill = GridBagConstraints.BOTH;
		gbc_mappaComboBox.gridx = 1;
		gbc_mappaComboBox.gridy = 5;
		Mappa.add(mappaComboBox, gbc_mappaComboBox);
		
		lblDimensione = new JLabel("Dimensione");
		GridBagConstraints gbc_lblDimensione = new GridBagConstraints();
		gbc_lblDimensione.anchor = GridBagConstraints.EAST;
		gbc_lblDimensione.insets = new Insets(0, 0, 5, 5);
		gbc_lblDimensione.gridx = 0;
		gbc_lblDimensione.gridy = 6;
		Mappa.add(lblDimensione, gbc_lblDimensione);
		
		dimensioneComboBox = new JComboBox();
		dimensioneComboBox.setModel(new DefaultComboBoxModel(new String[] {"640x640", "320x320"}));
		GridBagConstraints gbc_dimensioneComboBox = new GridBagConstraints();
		gbc_dimensioneComboBox.insets = new Insets(0, 0, 5, 5);
		gbc_dimensioneComboBox.fill = GridBagConstraints.BOTH;
		gbc_dimensioneComboBox.gridx = 1;
		gbc_dimensioneComboBox.gridy = 6;
		Mappa.add(dimensioneComboBox, gbc_dimensioneComboBox);
		
		btnDownload = new JButton("Download");
		btnDownload.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
				jg = new JGraph(new DefaultGraphModel());
				
				String url = staticMapsURL + c;
				
				try {
					if(localitaTextField.getText().isEmpty()) {
						
						lat = Double.valueOf(latitudineText.getText());
						lng = Double.valueOf(longitudineText.getText());
						
						url = url + lat + "," + lng + and;
						
					} else
						url = url + URLEncoder.encode(localitaTextField.getText(), "UTF-8");
					
					scala = (Integer) scalaSpinner.getValue();
					zoom = (Integer) zoomSpinner.getValue();
					
					String dim = dimensioneComboBox.getSelectedItem().toString();
					
					url = url + sc + scala + and + z + zoom + and 
							+ f + formatoComboBox.getSelectedItem().toString() + and
							+ t + mappaComboBox.getSelectedItem().toString() + and
							+ si + dim + and + sensor;
					
					System.out.println("URL: " + url);

					deltaX = Integer.parseInt(dim.split("x")[0])>>1;
					deltaY = Integer.parseInt(dim.split("x")[1])>>1;
					
					//Scarica la mappa statica dalla URL
					URL gmaps = new URL(url);
					map = ImageIO.read(gmaps);
					//Mette un'immagine su una JLabel
					mappaLabel = new JLabel(new ImageIcon(map));
					
					int size = deltaX*2*scala;
					if (size > mappaPanel.getHeight()) {				
						gbl_mappaPanel.columnWidths[1] = mappaPanel.getWidth();
						gbl_mappaPanel.rowHeights[1] = mappaPanel.getHeight();
					}
					//Imposta lo sfondo di JGraph con la JLabel precedente
					jg.setPreferredSize(new Dimension(size,size));
					jg.setBackgroundComponent(mappaLabel);
					//Aggiunge gli scroll
					mappaScrollPane.setPreferredSize(jg.getPreferredSize());
					mappaScrollPane.setViewportView(jg);
//					mappaPanel.revalidate();
					
					btnGrafo.setEnabled(true);
					if(btnGrafo.getText().startsWith("Rigenera"))
						btnGrafo.setText("Genera Grafo");
					
					percorsiSpinner.setEnabled(true);
					
					//Calcolo coordinate e margini
					
					confineN = InfoMaps.regolaLatConPixel(lat, -deltaY, zoom,0);
					confineS = InfoMaps.regolaLatConPixel(lat, deltaY, zoom,0);
					confineW = InfoMaps.regolaLongConPixel(lng,-deltaX, zoom,0);
					confineE = InfoMaps.regolaLongConPixel(lng,deltaX, zoom,0);
					
					System.out.println("deltaX=" + deltaX + " deltaY=" + deltaY);
					System.out.println("confine Nord=" + InfoMaps.format6(confineN) + " confine Sud=" + InfoMaps.format6(confineS));
					System.out.println("confine Ovest=" + InfoMaps.format6(confineW) + " confine Est=" + InfoMaps.format6(confineE));
		
					enableAllTab(false);
					
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (NumberFormatException e)  {
					e.printStackTrace();
				}
				
			}
		});
		GridBagConstraints gbc_btnDownload = new GridBagConstraints();
		gbc_btnDownload.insets = new Insets(0, 0, 5, 5);
		gbc_btnDownload.gridwidth = 2;
		gbc_btnDownload.fill = GridBagConstraints.BOTH;
		gbc_btnDownload.gridx = 0;
		gbc_btnDownload.gridy = 7;
		Mappa.add(btnDownload, gbc_btnDownload);
		
		lblPercorsi = new JLabel("Percorsi");
		GridBagConstraints gbc_lblPercorsi = new GridBagConstraints();
		gbc_lblPercorsi.insets = new Insets(0, 0, 5, 5);
		gbc_lblPercorsi.gridx = 0;
		gbc_lblPercorsi.gridy = 8;
		Mappa.add(lblPercorsi, gbc_lblPercorsi);
		
		percorsiSpinner = new JSpinner();
		percorsiSpinner.setModel(new SpinnerNumberModel(2, 2, 20, 1));
		GridBagConstraints gbc_percorsiSpinner = new GridBagConstraints();
		gbc_percorsiSpinner.anchor = GridBagConstraints.WEST;
		gbc_percorsiSpinner.insets = new Insets(0, 0, 5, 5);
		gbc_percorsiSpinner.gridx = 1;
		gbc_percorsiSpinner.gridy = 8;
		Mappa.add(percorsiSpinner, gbc_percorsiSpinner);
		
		btnGrafo = new JButton("Genera Grafo");
		btnGrafo.setEnabled(false);
		btnGrafo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				grafo = new Grafo();
				//Imposta l'adapter su JGraphT
				jg.setModel(grafo.getGraphAdapter());
				//Resetta i valori statici della classe grafo
				Grafo.resetNodiPercorso();
				Grafo.resetIdNodo();
				//Reimposta il contatore dei percorsi
				textCurrent.setText("1");
				//Cambia il testo del tasto genera grafo
				if(btnGrafo.getText().startsWith("Genera"))
					btnGrafo.setText("Rigenera Grafo");
				//Mette il MouseActionListener creato su JGraphT 
				mapMouse = new MapMouseActionListener();
				jg.addMouseListener(mapMouse);
				
				percorsiSpinner.setEnabled(false);
				btnFine.setEnabled(false);
				enableAllTab(false);
				
			}
		});
		GridBagConstraints gbc_btnGrafo = new GridBagConstraints();
		gbc_btnGrafo.insets = new Insets(0, 0, 5, 5);
		gbc_btnGrafo.gridwidth = 2;
		gbc_btnGrafo.fill = GridBagConstraints.BOTH;
		gbc_btnGrafo.gridx = 0;
		gbc_btnGrafo.gridy = 9;
		Mappa.add(btnGrafo, gbc_btnGrafo);
		
		textCurrent = new JTextField();
		textCurrent.setBackground(Color.LIGHT_GRAY);
		textCurrent.setHorizontalAlignment(SwingConstants.CENTER);
		textCurrent.setMinimumSize(new Dimension(40, 27));
		textCurrent.setEditable(false);
		textCurrent.setText("1");
		GridBagConstraints gbc_textCurrent = new GridBagConstraints();
		gbc_textCurrent.anchor = GridBagConstraints.WEST;
		gbc_textCurrent.insets = new Insets(0, 0, 5, 5);
		gbc_textCurrent.gridx = 1;
		gbc_textCurrent.gridy = 10;
		Mappa.add(textCurrent, gbc_textCurrent);
		textCurrent.setColumns(10);
		
		btnFine = new JButton("Fine Percorso");
		btnFine.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				//Reimposta il contatore dei nodi del percorso
				Grafo.resetNodiPercorso();
				//Incrementa il contatore dei percorsi fino a che non
				//raggiunge il valore preimpostato nello spinner
				int percorso = Integer.valueOf(textCurrent.getText());
				if (++percorso <= (Integer)percorsiSpinner.getValue())
					textCurrent.setText(Integer.toString(percorso));
				else {
					//Rimuove il MouseActionListener per non catturare
					//più i click
					jg.removeMouseListener(mapMouse);
					enableAllTab(true);
				}
				btnFine.setEnabled(false);
			}
		});
		btnFine.setEnabled(false);
		GridBagConstraints gbc_btnFine = new GridBagConstraints();
		gbc_btnFine.insets = new Insets(0, 0, 0, 5);
		gbc_btnFine.fill = GridBagConstraints.BOTH;
		gbc_btnFine.gridwidth = 2;
		gbc_btnFine.gridx = 0;
		gbc_btnFine.gridy = 11;
		Mappa.add(btnFine, gbc_btnFine);
		
		Cammino = new JPanel();
		algTabbedPane.addTab("Cammino", null, Cammino, null);
		GridBagLayout gbl_Cammino = new GridBagLayout();
		gbl_Cammino.columnWidths = new int[]{0, 0, 0, 0, 0};
		gbl_Cammino.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_Cammino.columnWeights = new double[]{0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		gbl_Cammino.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		Cammino.setLayout(gbl_Cammino);
		
		lblDijkstra = new JLabel("Algoritmo di Dijkstra");
		GridBagConstraints gbc_lblDijkstra = new GridBagConstraints();
		gbc_lblDijkstra.gridwidth = 4;
		gbc_lblDijkstra.insets = new Insets(0, 0, 5, 0);
		gbc_lblDijkstra.gridx = 0;
		gbc_lblDijkstra.gridy = 0;
		Cammino.add(lblDijkstra, gbc_lblDijkstra);
		
		lblNodo1 = new JLabel("Nodo 1");
		GridBagConstraints gbc_lblNodo1 = new GridBagConstraints();
		gbc_lblNodo1.fill = GridBagConstraints.BOTH;
		gbc_lblNodo1.insets = new Insets(0, 0, 5, 5);
		gbc_lblNodo1.gridx = 1;
		gbc_lblNodo1.gridy = 2;
		Cammino.add(lblNodo1, gbc_lblNodo1);
		
		nodo1ComboBox = new JComboBox();
		nodo1ComboBox.setEnabled(false);
		GridBagConstraints gbc_nodo1ComboBox = new GridBagConstraints();
		gbc_nodo1ComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_nodo1ComboBox.fill = GridBagConstraints.BOTH;
		gbc_nodo1ComboBox.gridx = 3;
		gbc_nodo1ComboBox.gridy = 2;
		Cammino.add(nodo1ComboBox, gbc_nodo1ComboBox);
		
		lblNodo2 = new JLabel("Nodo 2");
		GridBagConstraints gbc_lblNodo2 = new GridBagConstraints();
		gbc_lblNodo2.fill = GridBagConstraints.BOTH;
		gbc_lblNodo2.insets = new Insets(0, 0, 5, 5);
		gbc_lblNodo2.gridx = 1;
		gbc_lblNodo2.gridy = 4;
		Cammino.add(lblNodo2, gbc_lblNodo2);
		
		nodo2ComboBox = new JComboBox();
		nodo2ComboBox.setEnabled(false);
		GridBagConstraints gbc_nodo2ComboBox = new GridBagConstraints();
		gbc_nodo2ComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_nodo2ComboBox.fill = GridBagConstraints.BOTH;
		gbc_nodo2ComboBox.gridx = 3;
		gbc_nodo2ComboBox.gridy = 4;
		Cammino.add(nodo2ComboBox, gbc_nodo2ComboBox);
		
		btnDijkstra = new JButton("Calcola");
		btnDijkstra.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				/*
				 * Calcolare il percorso usando il cammino minimo
				 * con Dijkstra implementato con una classe a 
				 * parte utilizzando jgrapht
				 */
				
				String nodo1 = nodo1ComboBox.getSelectedItem().toString(),
						nodo2 = nodo2ComboBox.getSelectedItem().toString();
				
				costoTextField.setText("0 Km");
				
				if (nodo1.equals(nodo2))
					JOptionPane.showMessageDialog(frmGraphtheory,
								"I nodi devono essere differenti!");
				else{
					DijkstraShortestPath<ConvPoint, DefaultWeightedEdge> 
							dijkstra = new DijkstraShortestPath<ConvPoint,
																DefaultWeightedEdge>(
									grafo.getGrafo(),
									grafo.cercaVertice(Integer.valueOf(nodo1)),
									grafo.cercaVertice(Integer.valueOf(nodo2))
								);
					
					grafo.resetAttributiLati();
					List<DefaultWeightedEdge> path = dijkstra.getPathEdgeList();
					if (path == null)
						JOptionPane.showMessageDialog(frmGraphtheory,
								"I nodi selezionati sono di grafi non connessi!");
					else {
						for (DefaultWeightedEdge i: path) {
							grafo.coloraLato(i,Color.GREEN);
						}
						costoTextField.setText(InfoMaps.format3(dijkstra.getPathLength()) + " Km");
					}
				}
				
			}
		});
		
		lblCosto = new JLabel("Costo");
		GridBagConstraints gbc_lblCosto = new GridBagConstraints();
		gbc_lblCosto.insets = new Insets(0, 0, 5, 5);
		gbc_lblCosto.gridx = 1;
		gbc_lblCosto.gridy = 6;
		Cammino.add(lblCosto, gbc_lblCosto);
		
		costoTextField = new JTextField();
		costoTextField.setEnabled(false);
		costoTextField.setEditable(false);
		costoTextField.setText("0 Km");
		GridBagConstraints gbc_costoTextField = new GridBagConstraints();
		gbc_costoTextField.insets = new Insets(0, 0, 5, 0);
		gbc_costoTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_costoTextField.gridx = 3;
		gbc_costoTextField.gridy = 6;
		Cammino.add(costoTextField, gbc_costoTextField);
		costoTextField.setColumns(10);
		btnDijkstra.setEnabled(false);
		GridBagConstraints gbc_btnDijkstra = new GridBagConstraints();
		gbc_btnDijkstra.gridx = 3;
		gbc_btnDijkstra.gridy = 7;
		Cammino.add(btnDijkstra, gbc_btnDijkstra);
		algTabbedPane.setEnabledAt(1, false);
		
		Albero = new JPanel();
		algTabbedPane.addTab("Albero", null, Albero, null);
		GridBagLayout gbl_Albero = new GridBagLayout();
		gbl_Albero.columnWidths = new int[]{328, 0};
		gbl_Albero.rowHeights = new int[]{0, 0, 0, 0};
		gbl_Albero.columnWeights = new double[]{0.0, Double.MIN_VALUE};
		gbl_Albero.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
		Albero.setLayout(gbl_Albero);
		
		lblKruskal = new JLabel("Algoritmo di Kruskal");
		GridBagConstraints gbc_lblKruskal = new GridBagConstraints();
		gbc_lblKruskal.insets = new Insets(0, 0, 5, 0);
		gbc_lblKruskal.gridx = 0;
		gbc_lblKruskal.gridy = 0;
		Albero.add(lblKruskal, gbc_lblKruskal);
		
		btnKruskal = new JButton("Calcola");
		btnKruskal.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				/*
				 * Calcolare l'albero ricoprente minimo con 
				 * Kruskal implementato con una classe a parte
				 * utilizzando jgrapht
				 */
				
				KruskalMinimumSpanningTree<ConvPoint, DefaultWeightedEdge>
						kruskal = new KruskalMinimumSpanningTree<ConvPoint,
																DefaultWeightedEdge>
							(grafo.getGrafo());
				
				
				grafo.resetAttributiLati();
				for (DefaultWeightedEdge i: kruskal.getEdgeSet()) {
					grafo.coloraLato(i,Color.CYAN);
				}
				
			}
		});
		btnKruskal.setEnabled(false);
		GridBagConstraints gbc_btnKruskal = new GridBagConstraints();
		gbc_btnKruskal.gridx = 0;
		gbc_btnKruskal.gridy = 2;
		Albero.add(btnKruskal, gbc_btnKruskal);
		algTabbedPane.setEnabledAt(2, false);
		frmGraphtheory.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	//Metodo per abilitare i e tab per gli algoritmi
	private void enableAllTab(boolean enable) {
		enableCammino(enable);
		enableAlbero(enable);
		if (enable)
			grafo.stampaGrafo();
	}
	
	private void enableCammino(boolean enable) {
		
//		Aggiunta di tutti i nodi nella lista
//			for Ogni nodo
//				modelNodo.add(Nome nodo)
//
//		Volendo si può includere durante la generazione del grafo
//		ricordandosi di svuotarlo prima di ogni generazione

//		//ESEMPIO
//		
//		modelNodo.add("1");
//		modelNodo.add("2");
//		modelNodo.add("3");
//		
//		//FINE ESEMPIO
		if (enable)
			for (ConvPoint i: grafo.getVertex())
				modelNodo.add("" + i.getId());
		else
			modelNodo.clear();
		
//		Creazione dei modelli per le 2 ComboBox
		nodo1ComboBox.setModel(new DefaultComboBoxModel(modelNodo.toArray()));
		nodo2ComboBox.setModel(new DefaultComboBoxModel(modelNodo.toArray()));
		
		nodo1ComboBox.setEnabled(enable);
		nodo2ComboBox.setEnabled(enable);
		btnDijkstra.setEnabled(enable);
		costoTextField.setEnabled(enable);
		algTabbedPane.setEnabledAt(1, enable);
		
	}
	
	private void enableAlbero(boolean enable) {
		
		btnKruskal.setEnabled(enable);
		algTabbedPane.setEnabledAt(2, enable);
		
	}
}
